package com.cch.cooperation.api.zone.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cch.cooperation.api.auth.service.UserServiceImpl;
import com.cch.cooperation.api.zone.dto.ZonePostCommentDTO;
import com.cch.cooperation.api.zone.dto.ZonePostDTO;
import com.cch.cooperation.api.zone.dto.ZonePostLikeDTO;
import com.cch.cooperation.api.zone.dto.ZonePostLikeTriggerDTO;
import com.cch.cooperation.biz.common.lock.Locker;
import com.cch.cooperation.biz.common.util.BeanUtilEx;
import com.cch.cooperation.common.exception.BizException;
import com.cch.cooperation.common.util.SnowflakeIdUtil;
import com.cch.cooperation.dao.auth.model.User;
import com.cch.cooperation.dao.zone.mapper.ZonePostLikeMapper;
import com.cch.cooperation.dao.zone.model.ZonePostComment;
import com.cch.cooperation.dao.zone.model.ZonePostLike;
import com.google.common.collect.Lists;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ZonePostLikeServiceImpl {

    @Resource
    private ZonePostLikeMapper mapper;
    @Lazy
    @Resource
    private ZonePostServiceImpl zonePostService;
    @Resource
    private UserServiceImpl userService;

    public List<ZonePostLikeDTO> getByZonePostIds(List<String> zonePostIds) {
        if (CollUtil.isEmpty(zonePostIds)) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<ZonePostLike> query = new LambdaQueryWrapper<>();
        query.in(ZonePostLike::getZonePostId, zonePostIds);
        query.orderByDesc(ZonePostLike::getCreateTime);
        List<ZonePostLike> likes = mapper.selectList(query);
        // 查询关联用户
        List<String> userIds = likes.stream().map(o -> o.getUserId()).distinct().collect(Collectors.toList());
        Map<String, User> userMap = userService.getMapByIds(userIds);
        // 聚合关联信息
        List<ZonePostLikeDTO> result = new ArrayList<>();
        for (ZonePostLike item : likes) {
            ZonePostLikeDTO like = BeanUtilEx.copy(item, ZonePostLikeDTO.class);
            like.setUser(userMap.get(like.getUserId()));
            result.add(like);
        }
        return result;
    }

    @Locker(key = "'LOCK:ZONE_POST_LIKE:TRIGGER:' + #req.zonePostId")
    public ZonePostLikeDTO trigger(@Valid ZonePostLikeTriggerDTO req) {
        ZonePostDTO post = zonePostService.getById(req.getZonePostId());
        if (ObjectUtil.isNull(post)) {
            throw new BizException("空间动态不存在");
        }
        LambdaQueryWrapper<ZonePostLike> query = new LambdaQueryWrapper<>();
        query.eq(ZonePostLike::getZonePostId, req.getZonePostId());
        query.eq(ZonePostLike::getUserId, req.getUserId());
        if (mapper.selectCount(query) < 1) {
            // 点赞
            ZonePostLike like = new ZonePostLikeDTO();
            like.setId(SnowflakeIdUtil.getIdStr());
            like.setZoneId(post.getZoneId());
            like.setZonePostId(post.getId());
            like.setUserId(req.getUserId());
            like.setCreateTime(new Date());
            mapper.insert(like);
            return getByZonePostIds(Lists.newArrayList(req.getZonePostId())).stream().filter(o -> o.getId().equals(like.getId())).findFirst().orElse(null);
        }
        // 取消赞
        mapper.delete(query);
        return null;
    }

    public Map<String, List<ZonePostLikeDTO>> getMapByZonePostIds(List<String> zonePostIds) {
        List<ZonePostLikeDTO> list = getByZonePostIds(zonePostIds);
        return list.stream().collect(Collectors.groupingBy(o -> o.getZonePostId()));
    }

    public void deleteByZonePostId(String zonePostId) {
        LambdaQueryWrapper<ZonePostLike> query = new LambdaQueryWrapper<>();
        query.eq(ZonePostLike::getZonePostId, zonePostId);
        mapper.delete(query);
    }

}
